home *** CD-ROM | disk | FTP | other *** search
/ The PC-SIG Library 10 / The PC-Sig Library - Shareware for the IBM PC and Compatibles (PC-SIG)(Tenth Edition Disks 1-2804)(1991).iso / PC_SIGCD / 04 / 2 / DISK0427.ZIP / TURBORUN.ASM < prev    next >
Assembly Source File  |  1985-04-15  |  19KB  |  404 lines

  1.  
  2. Page 60,132
  3. Title TURBORUN a utility for Turbo Pascal, MS/PC-DOS v2.xx
  4. Name TurboRun
  5.  
  6. ;************************************************************************
  7. ;*                                                                      *
  8. ;*                            T U R B O R U N                           *
  9. ;*                              Version 1.1                             *
  10. ;*                                                                      *
  11. ;*                 By John Cooper       John Falconer                   *
  12. ;*                    (913) 262-8451    (415) 521-7245                  *
  13. ;*                    CIS  74775,756    CIS  72435,1617                 *
  14. ;*                                                                      *
  15. ;************************************************************************
  16.  
  17. Comment*
  18.  
  19. Revision History
  20.         Version 1.0 was successfully tested on 12/10/84.
  21.                    By John Cooper
  22.         
  23.         Updated to Version 1.0A on 12/22/84. 
  24.                    By John Falconer  
  25.                                       
  26.             1.  Changed ssmax from a constant to a code-base-relative
  27.                 value.  This change allows Turborun to be used with
  28.                 different versions of Turbo Pascal.  Although undocumented,
  29.                 the four versions of Turbo I tested all store their
  30.                 maximum stack segment size as a word located seven bytes
  31.                 ahead of the beginning of user code. 
  32.             2.  Added code to determine the length of the command line
  33.                 which is passed to the child process.  Moved the child's
  34.                 command line starting point to PSP+081H as called for in
  35.                 the DOS manual (Ver 2.0 page E-6) and placed the length
  36.                 byte for the command line at PSP+080H.  This allows the
  37.                 command line passed to the child to be used as a string
  38.                 with string[0] containing the valid length.  Note that
  39.                 a carriage return is placed at the end of the passed command
  40.                 line but that it is not counted in the length.  Note also
  41.                 that this change corrupts the CmdLine variable passed
  42.                 to Turborun by changing the last character of the file
  43.                 name to the length of the child's CmdLine.
  44.             3.  Changed original code so that all characters on the command
  45.                 line are passed on to the child.  This is as called for in 
  46.                 the DOS manual.  Previously the first terminator (usually
  47.                 a space) was skipped over.
  48.             4.  Corrected a few minor documentation errors.
  49.  
  50. Note:           The EXEC call does not support IO-Redirection on the command
  51.                 line.  
  52.  
  53.         Updated to Version 1.0B January 10, 1985
  54.                    By John Cooper 
  55.  
  56.             1.  A note concerning the lack of IO-redirection support
  57.                 by the MS/PC DOS EXEC function call, the call which is
  58.                 at the heart of this program, was ammended, as it has 
  59.                 been determined that, at least in the case of MS-DOS 2.11,
  60.                 EXEC does provide full IO-redirection, via the command line
  61.                 symbols "> < |", if the command processor is envolked ahead 
  62.                 of the child.  
  63.   
  64.                 <Child> [FCB-1 [FCB-2]] >PIPEOUT <PIPEIN  
  65.  
  66.                 The above will NOT work, however,
  67.  
  68. [path][drive]COMMAND.COM /C <Child> [FCB-1 [FCB-2]] >PIPEOUT <PIPEIN
  69.                 
  70.                 should work just fine.
  71.  
  72.  
  73.             2.  Changed the way in which the program detects the end
  74.                 of the childs name, to include all filename separators,
  75.                 as listed on page 1-88 of MS-DOS v2.0 Programmer's 
  76.                 Reference, except the back-slash (\) and colon (:).  These
  77.                 two were excluded because the program needs to accept a
  78.                 full-path name, which could include these symbols.  Pre-
  79.                 viously only a space or null was considered a terminator.
  80.                 This change was recommended but not implemented in version
  81.                 1.0A.
  82.  
  83.             3.  Added notes on installation concerning the requirement,
  84.                 introduced by an enhancement made in 1.0A, that the
  85.                 external declaration of this program be the first in the
  86.                 Turbo source code.  Also added some warnings and documentation
  87.                 notes.
  88.  
  89.         Updated to Version 1.1 March 17, 1985
  90.                 By John Falconer
  91.  
  92.             1.  A "bug" in the way memory allocation is calculated and 
  93.                 set to protect Turbo's SSEG was fixed.  The program is now 
  94.                 known to function with such large applications as 1-2-3 and
  95.                 Dbase III. 
  96.  
  97. *
  98. Page
  99. Comment*
  100.  
  101.                          - - - W A R N I N G - - -
  102.         Although every effort has been made, by the two authors, to
  103.         ensure that this program will perform as specified, there are
  104.         may be programs which will not function correctly when envoked
  105.         from Turbo, via Turborun, but will do just fine if envoked
  106.         from COMMAND.COM.  An excellent example is WordStar(tm).  In
  107.         some, but not all, cases this can be solved by first envoking
  108.         COMMAND.COM and then envoking the child from COMMAND.COM.  
  109.         Assume that there is a program, WORKING.COM, that will not
  110.         work from Turborun but does work from DOS.  The following
  111.         command line might help;
  112.  
  113.          COMMAND.COM /c WORKING.COM
  114.  
  115.         This of course assume that there is not a shortage of
  116.         memory of some other explainable problem.  The switch, /c,
  117.         is included to force COMMAND.COM to return control to the
  118.         parent after the processing of its, COMMAND.COM's, command line.
  119.  
  120.  
  121. Installation Notes:
  122.         The enhancement to provide for a version-independent SSMAX,
  123.         provided by John F., has introduced the additional requirement
  124.         that this external be the first code generating structute in
  125.         the Turbo Pascal source code, i.e. make TurboRun the first 
  126.         procedure, following the Const, Type, and Var blocks, in the
  127.         main program.  Turborun assumes it is the first and can,
  128.         therefore, find the SSMAX word exactly seven bytes prior to
  129.         its own base address.
  130.  
  131.  
  132.         Memory Compiles.
  133.                 The use of this program in "memory mode" is not recom-
  134.                 mended.  Turbo seems to dislike having its memory 
  135.                 limited, which is required to run the child.  It may
  136.                 work but it is, at best, risky!  The prefered method
  137.                 is to do a memory-compile, if possible, then switch to
  138.                 Com and limit the Maximum Stack Size and compile again,
  139.                 this time producing a COM file.  If compilation to memory
  140.                 is not possible, due to lack of memory or the use of 
  141.                 Overlays, you MUST implement some sort of patch to
  142.                 work around Turbo Pascal 2.0B's known "bug" in its handling
  143.                 of externals greater that 128-bytes in length.  The "bug"
  144.                 is easy to work around, by either loading the external
  145.                 at run-time(recommended) or converting it to an INLINE 
  146.                 $Include file.
  147.  
  148.  
  149.         Limiting the Stack Segment for Turbo Pascal.
  150.                 If the Stack Size is not limited, at compile-time, then
  151.                 Turbo Pascal may want to consume all of the system's 
  152.                 available RAM.  Of course, that precludes the use of child
  153.                 processes because the BLOCK call will fail, due to a lack
  154.                 of resources.   It is, therefore, recommended that you limit
  155.                 Maximum Stack Size to just enough memory to allow the Pascal
  156.                 program to operate, this will leave the balance of your 
  157.                 system's resources available for child processes.  
  158.  
  159.  
  160.         Terminate But Stay Resident.
  161.                 Programs which use "Terminate but stay resident" or 
  162.                 "Keep process" to terminate but keep itself in memory should
  163.                 not be run from Turborun.  The reason is that will cause
  164.                 DOS to attempt to set the allocation block map to prevent
  165.                 overlaying of the child.  If the system survives this, it
  166.                 still leave DOS in an unpredictable state.  
  167.  
  168.  
  169.         Exit codes.
  170.                 In order for the parent to correctly detect the reason the
  171.                 child terminated the child must pass that infomation back,
  172.                 so that the Get Return Code can find it.  Many currently,
  173.                 available programs do not provide this and hence the code
  174.                 value passed back to RetCode may not reflect the actual
  175.                 reason the child was terminated.  An example is COMMAND.COM.
  176.  
  177.         "BUGS".
  178.                 If you encounter difficulties using this program or you find
  179.                 "bugs" in it, please contact either author or the latest 
  180.                 revisor.
  181.  
  182.  
  183.         After this source code is assembled, linked, and converted to 
  184.         a COM file it should be included as an external procedure
  185.         within the Turbo Pascal source file.  The external should be
  186.         of the form shown below.
  187.  
  188.         Procedure GoForIt(Var RetCode:Integer; Var Cmdline);
  189.                 External 'TurboRun.com';
  190.  
  191.         Cmdline can be either type-CHAR or type-STRING.  If the latter
  192.         is used you should pass CmdLine[1] to skip the length byte.
  193.  
  194.         Format of CmdLine:
  195. path-name-to-child [<sp> First-FCB [<sp> Second-FCB [<sp> switchs and/or IO redirection]]] #0
  196.  
  197.         Notice that the Cmdline to followed by a byte of 0, this is binary 0
  198.         not ASCII 0. <-- VERY IMPORTANT! 
  199.  
  200.         The variable, RetCode, will contain the return code from the
  201.         child process.  RetCode is actually used as two, seperate,
  202.         byte-length variables.  The table below explains how to interpret
  203.         this variable in terms of its high and low bytes.
  204.  
  205.         High byte
  206.                 0 : Normal Termination, No error
  207.                 1 : Child was terminated via by CONTROL-C
  208.                 2 : Child was aborted because of a DOS Hard Error
  209.                 3 : Child used terminate-but-stay-resident
  210.                     (System needs to be rebooted)
  211.                 4 : EXEC call failed.
  212.                 8 : Memory allocation error, EXEC was not attempted
  213.  
  214.         In the cases of 0,1,2, and 3 the low byte has the value passed
  215.         back by the child.  Any of these values indicate that the EXEC
  216.         call was successful.  Programs which use terminate-but-stay-
  217.         resident should not be called by the program.
  218.  
  219.         In the case of 4 the low byte has the reason the EXEC failed.
  220.           2 : The path specified was invalid or not found.
  221.           8 : There was not enough memory for the process to be created.
  222.          11 : The process was an EXE format file and contained information
  223.               that was internally inconsistent.
  224.  
  225.         In the case of 8 the low byte has the reason the memory allocation
  226.         request failed.
  227.           7 : The arena was trashed because a user program has changed
  228.               memory that does not belong to it. System needs to be Rebooted.
  229.           8 : Insufficient memory.
  230.  
  231. *       
  232. Page      
  233. Subttl Main Program
  234. ;
  235. ;------------------- E Q U A T E S --------------------
  236. ;
  237. spsave  equ     cs:00fch        ;Storage for SP register
  238. sssave  equ     cs:00feh        ;Storage for SS register
  239. ;
  240. ;-------------------- M A C R O S ---------------------
  241. ;
  242. MsDos   Macro   function
  243.         If function lt 256
  244.         mov     ah,function
  245.         Else
  246.         mov     ax,function
  247.         EndIf
  248.         int     21h
  249.         EndM
  250. ;
  251. ;
  252. ;------------------ M A I N  P R O G R A M -----------------
  253. ;
  254. code            segment para public 'CODE'
  255.                 assume  cs:code,ds:nothing,es:code,ss:nothing
  256.  
  257.                 org 00h  
  258. run             proc    near
  259.                 call    entry   ;Find out where we were loaded
  260.                                 ;There is no return from this CALL
  261. separate        db     ';,=+"[]><| ',9,0 ;Filename separators
  262.                                 ;Excluding ":" and "\" which cannot appear in
  263.                                 ;a filename but can appear in a pathname.
  264.                 
  265. child           db      128 dup(?)      ;Path to child (with filename extension) 
  266. fcb1            db      16 dup(?)       ;Optional fcb
  267. fcb2            db      16 dup(?)       ;Optional fcb
  268. parablk         dw      0,12 dup(?)     ;Parameter block (DOS 2.0 Manual p. D-45)
  269. cmdstrt         dw      0               ;Offset to first char in child's CmdLine
  270. ssmax           dw      0               ;Storage for parent's maximum stack size, 
  271.                                         ;in paragraphs
  272.  
  273. entry:          pop     bx              ;Offset+3
  274.                 sub     bx,3            ;Actual offset address of RUN.COM
  275.                 pop     dx              ;Turbo(tm) return address 
  276.                 pop     si              ;Offset to command string
  277.                 pop     cx              ;Segment address of command string
  278.                 push    dx              ;Restore turbo's RET address
  279.                 mov     dx,si
  280.                 push    ds
  281.                 push    bp
  282.                 pushf
  283.  
  284.                 push    bx              ;Save bx temporarily
  285.                 sub     bx,7            ;Point to parent's max stack size
  286.                 mov     ax,cs:[bx]      ;Move it to ax
  287.                 pop     bx              ;Recover bx
  288.                 mov     [ssmax+bx],ax   ;Save the max stack size for SETBLOCK call
  289.  
  290.                 mov     ds,cx           ;Point to command string segment
  291.                 push    cs              ;Make ES=CS 
  292.                 pop     es
  293.                 mov     di,offset child ;Child process path name
  294.                 add     di,bx           ;Relocation offset
  295.                 cld                     ;Force direction
  296. cmdlp:          lodsb                   ;Get character
  297.                 push    di              ;Save DI
  298.                 mov     cx,13           ;look for any of 13 filename separators
  299.                 mov     di,offset separate
  300.                 add     di,bx           ;Relocation offset
  301.                 repnz   scasb           ;Look for match
  302.                 jz      endstr          ;Exit if a separator is found
  303.                 pop     di              ;Otherwise, retrieve DI and continue
  304.                 stosb                   ;Store byte
  305.                 jmp     cmdlp           ;Try next character
  306. endstr:         pop     di              ;Retrieve DI
  307.                 mov     [cmdstrt+bx],si ;Pointer to first char in child's CmdLine
  308.                 mov     al,0            ;Put terminating 0 in child path
  309.                 stosb
  310.                 dec     si              ;Back up one for stosb
  311.                 dec     si              ;Back up one for the length byte
  312.  
  313. ;ds:si point to the childs command line
  314.  
  315. u1:             mov     [parablk+2+bx],si ;Store offset address
  316.                 inc     si              ;Start parsing at head of child's CmdLine
  317.                 mov     cx,ds
  318.                 mov     [parablk+4+bx],cx ;Store segment address
  319.                 mov     di,offset fcb1  ;Setup to parse first filename
  320.                 add     di,bx           ;Relocation
  321.  
  322. ;di has offset from cs to default FCB passed at 5Ch
  323.  
  324.                 mov     [parablk+6+bx],di
  325.                 MsDos   2901h           ;Ignore leading separators
  326.                 mov     di,offset fcb2  ;Parse second filename
  327.                 add     di,bx           ;Relocation
  328.  
  329. ;di has offset from cs to default FCB passed at 6Ch
  330.  
  331.                 mov     [parablk+10+bx],di
  332.                 MsDos   2901h
  333. ;
  334. ;Place <cr> at end of CmdLine, calculate and store child's CmdLine length
  335. ;
  336. u2:             cmp     byte ptr ds:[si],0 ;Look for end of line
  337.                 jz      u3
  338.                 inc     si
  339.                 jmp     u2
  340. u3:             mov     byte ptr ds:[si],13
  341.  
  342.                 mov     ax,[cmdstrt+bx] ;Get pointer to first char in child's CmdLine
  343.                 xchg    ax,si           ;Swap it with current pointer
  344.                 dec     si              ;We don't include the <cr> in our length
  345.                 sub     ax,si           ;Calculate the length
  346.                 dec     si              ;Point to the length byte
  347.                 mov     byte ptr ds:[si],al ;Store calculated length there
  348.  
  349.                 mov     cx,cs           ;Setup segments in parameter block
  350.                 mov     [parablk+8+bx],cx
  351.                 mov     [parablk+12+bx],cx
  352.                 mov     [parablk+bx],0  ;Pass environment to child, unchanged
  353.  
  354. ;Now the childs parameter block is setup.
  355. ;All that remains is to allocate memory and go for it.
  356.  
  357.                 push    bx              ;Save reloc register
  358.                 mov     bx,[ssmax+bx]
  359.                 push    cx
  360.                 mov     cx,ss   
  361.                 add     bx,cx
  362.                 pop     cx
  363.                 sub     bx,cx
  364.                 MsDos   4ah             ;Modify memory allocation
  365.                 jnc     $+5
  366.                 jmp     alocer          ;Allocation error, Exit
  367.                 pop     bx              ;Recover reloc register
  368.                 push    bx              ;Save a copy on stack
  369.                 mov     dx,bx
  370.                 add     bx,offset parablk
  371.                 mov     [spsave],sp     ;Save SP
  372.                 mov     [sssave],ss     ;Save SS
  373.                 push    cs              ;Point ds:sx to child
  374.                 pop     ds
  375.                 add     dx,offset child
  376.                 MsDos   4b00h           ;Go for it
  377.                 cli                     ;Prevent interuption
  378.                 mov     sp,[spsave]     ;Recover SP
  379.                 mov     ss,[sssave]     ;Recover SS
  380.                 sti
  381.                 jnc     $+5
  382.                 jmp     runerr          ;Problems, Exit
  383.                 pop     bx              ;Get reloc register
  384.                 MsDos   4dh             ;Get return code from child
  385. getbac:         popf                    ;Turbo's Flags
  386.                 pop     bp              ;Turbo's BP
  387.                 pop     ds              ;Turbo's DS
  388.                 pop     cx              ;Return address
  389.                 pop     di              ;Offset to RC Variable
  390.                 pop     es              ;Segment of RC Variable
  391.                 mov     es:[di],ax      ;Store return code
  392.                 push    cx              ;Restore return address
  393.                 ret                     ;Back to Turbo
  394.  
  395. alocer:         pop     bx              ;Reloc register
  396.                 mov     ah,8            ;Indicate Allocation error
  397.                 jmp     getbac
  398. runerr:         pop     bx
  399.                 mov     ah,4            ;Indicate RUN error
  400.                 jmp     getbac
  401. run             endp
  402. code            ends
  403.                 end     run
  404.